package webapp.mvc.services.impl;

import com.google.common.base.Function;
import com.zoowii.jpa_utils.extension.Paginator;
import com.zoowii.jpa_utils.query.Expr;
import com.zoowii.jpa_utils.util.ListUtil;
import com.zoowii.jpa_utils.util.StringUtil;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.stereotype.Service;
import webapp.mvc.controllers.forms.CreateShopFeedbackForm;
import webapp.mvc.controllers.forms.CreateShopForm;
import webapp.mvc.controllers.forms.UpdateShopForm;
import webapp.mvc.enums.IntBooleans;
import webapp.mvc.exceptions.ShopException;
import webapp.mvc.models.*;
import webapp.mvc.services.IShopService;
import webapp.mvc.utils.TimeUtil;

import java.util.List;

@Service
public class ShopService implements IShopService {
    @Override
    public List<ShopEntity> getShops(String categoryId, Paginator paginator) {
        if(!StringUtil.isEmpty(categoryId)) {
            paginator = paginator.eq("categoryId", categoryId);
        }
        paginator.getOrders().add(Pair.of("collectCount", false));
        paginator.getOrders().add(Pair.of("commentCount", false));
        paginator.getOrders().add(Pair.of("modifyTime", false));
        return ShopEntity.find.findByPaginator(paginator);
    }

    @Override
    public List<ShopChangeRequestEntity> getShopChangeRequests(Paginator paginator) {
        paginator.getOrders().add(Pair.of("createTime", false));
        paginator = paginator.eq("deleted", IntBooleans.FALSE);
        List<ShopChangeRequestEntity> shopChangeRequestEntities = ShopChangeRequestEntity.find.findByPaginator(paginator);
        ListUtil.map(shopChangeRequestEntities, new Function<ShopChangeRequestEntity, Void>() {
            @Override
            public Void apply(ShopChangeRequestEntity shopChangeRequestEntity) {
                shopChangeRequestEntity.setShop(ShopEntity.find.byId(shopChangeRequestEntity.getShopId()));
                shopChangeRequestEntity.setCategory(ShopCategoryEntity.find.byId(shopChangeRequestEntity.getCategoryId()));
                return null;
            }
        });
        return shopChangeRequestEntities;
    }

    @Override
    public ShopEntity agreeShopChangeRequest(String requestId) {
        ShopChangeRequestEntity shopChangeRequestEntity = ShopChangeRequestEntity.find.byId(requestId);
        if (shopChangeRequestEntity == null) {
            return null;
        }
        boolean isNewShop = StringUtil.isEmpty(shopChangeRequestEntity.getShopId());
        ShopEntity shopEntity;
        if (!isNewShop) {
            shopEntity = ShopEntity.find.byId(shopChangeRequestEntity.getShopId());
            if (shopEntity == null) {
                shopChangeRequestEntity.delete();
                return null;
            }
        } else {
            shopEntity = new ShopEntity();
            shopEntity.setOwnerId(shopChangeRequestEntity.getRequestUserId());
        }
        shopEntity.setCategoryId(shopChangeRequestEntity.getCategoryId());
        shopEntity.setDescription(shopChangeRequestEntity.getDescription());
        shopEntity.setLogoUrl(shopChangeRequestEntity.getLogoUrl());
        shopEntity.setName(shopChangeRequestEntity.getName());
        shopEntity.setAddress(shopChangeRequestEntity.getAddress());
        shopEntity.setContact(shopChangeRequestEntity.getContact());
        shopEntity.setDiscount(shopChangeRequestEntity.getDiscount());
        shopEntity.setModifyTime(TimeUtil.currentTimestamp());
        if (isNewShop) {
            shopEntity.save();
        } else {
            shopEntity.update();
        }
        shopChangeRequestEntity.setDeleted(IntBooleans.TRUE);
        shopChangeRequestEntity.setPassed(IntBooleans.TRUE);
        shopChangeRequestEntity.setModifyTime(TimeUtil.currentTimestamp());
        shopChangeRequestEntity.update();
        return shopEntity;
    }

    @Override
    public ShopChangeRequestEntity disagreeShopChangeRequest(String requestId) {
        ShopChangeRequestEntity shopChangeRequestEntity = ShopChangeRequestEntity.find.byId(requestId);
        if (shopChangeRequestEntity == null) {
            return null;
        }
        shopChangeRequestEntity.setDeleted(IntBooleans.TRUE);
        shopChangeRequestEntity.setModifyTime(TimeUtil.currentTimestamp());
        shopChangeRequestEntity.update();
        return shopChangeRequestEntity;
    }

    @Override
    public List<ShopEntity> searchShops(String keyword, Paginator paginator) {
        if (!StringUtil.isEmpty(keyword)) {
            keyword = "%" + keyword + "%";
            paginator = paginator.addExpression(Expr.createOR(Expr.createLIKE("name", keyword),
                    Expr.createLIKE("description", keyword)));
        }
        paginator.getOrders().add(Pair.of("collectCount", false));
        paginator.getOrders().add(Pair.of("commentCount", false));
        paginator.getOrders().add(Pair.of("modifyTime", false));
        return ShopEntity.find.findByPaginator(paginator);
    }

    @Override
    public ShopEntity createShop(String userId, CreateShopForm createShopForm) throws ShopException {
        if(ShopEntity.find.findByName(createShopForm.getName())!=null) {
            throw new ShopException("商户名称" + createShopForm.getName() + "已经存在");
        }
        ShopChangeRequestEntity shopChangeRequestEntity = new ShopChangeRequestEntity();
        shopChangeRequestEntity.setShopId("");
        shopChangeRequestEntity.setRequestUserId(userId);
        shopChangeRequestEntity.setAddress(createShopForm.getAddress());
        shopChangeRequestEntity.setContact(createShopForm.getContact());
        shopChangeRequestEntity.setName(createShopForm.getName());
        shopChangeRequestEntity.setDescription(createShopForm.getDescription());
        shopChangeRequestEntity.setLogoUrl(createShopForm.getLogoUrl());
        shopChangeRequestEntity.setCategoryId(createShopForm.getCategoryId());
        shopChangeRequestEntity.setDiscount(createShopForm.getDiscount());
        shopChangeRequestEntity.save();
//        ShopEntity shopEntity = new ShopEntity();
//        shopEntity.setCategoryId(createShopForm.getCategoryId());
//        shopEntity.setOwnerId(userId);
//        shopEntity.setDescription(createShopForm.getDescription());
//        shopEntity.setLogoUrl(createShopForm.getLogoUrl());
//        shopEntity.setName(createShopForm.getName());
//        shopEntity.save();
        return null;
    }

    @Override
    public ShopEntity updateShop(String updateUserId, String shopId, UpdateShopForm updateShopForm) throws ShopException {
        ShopEntity shopEntity = ShopEntity.find.byId(shopId);
        if(shopEntity == null || shopEntity.getDeleted() != IntBooleans.FALSE) {
            throw new ShopException("找不到商户" + shopId);
        }
        ShopChangeRequestEntity shopChangeRequestEntity = new ShopChangeRequestEntity();
        shopChangeRequestEntity.setRequestUserId(updateUserId);
        shopChangeRequestEntity.setShopId(shopEntity.getId());
        shopChangeRequestEntity.setName(shopEntity.getName());
        shopChangeRequestEntity.setDescription(shopEntity.getDescription());
        shopChangeRequestEntity.setAddress(shopEntity.getAddress());
        shopChangeRequestEntity.setContact(shopEntity.getContact());
        shopChangeRequestEntity.setLogoUrl(shopEntity.getLogoUrl());
        shopChangeRequestEntity.setCategoryId(shopEntity.getCategoryId());
        shopChangeRequestEntity.setDiscount(updateShopForm.getDiscount());
        if(!StringUtil.isEmpty(updateShopForm.getName())) {
            if (!shopEntity.getName().equals(updateShopForm.getName())) {
                ShopEntity shopWithNewName = ShopEntity.find.findByName(updateShopForm.getName());
                if(shopWithNewName != null) {
                    throw new ShopException("商户名称" + updateShopForm.getName() + "已经存在");
                }
//                shopEntity.setName(updateShopForm.getName());
                shopChangeRequestEntity.setName(updateShopForm.getName());
            }
        }
        if(!StringUtil.isEmpty(updateShopForm.getDescription())) {
//            shopEntity.setDescription(updateShopForm.getDescription());
            shopChangeRequestEntity.setDescription(updateShopForm.getDescription());
        }
        if(!StringUtil.isEmpty(updateShopForm.getCategoryId())) {
//            shopEntity.setCategoryId(updateShopForm.getCategoryId());
            shopChangeRequestEntity.setCategoryId(updateShopForm.getCategoryId());
        }
        if(!StringUtil.isEmpty(updateShopForm.getLogoUrl())) {
//            shopEntity.setLogoUrl(updateShopForm.getLogoUrl());
            shopChangeRequestEntity.setLogoUrl(updateShopForm.getLogoUrl());
        }
        if (!StringUtil.isEmpty(updateShopForm.getAddress())) {
            shopChangeRequestEntity.setAddress(updateShopForm.getAddress());
        }
        if (!StringUtil.isEmpty(updateShopForm.getContact())) {
            shopChangeRequestEntity.setContact(updateShopForm.getContact());
        }
//        shopEntity.setModifyTime(TimeUtil.currentTimestamp());
//        shopEntity.update();
        shopChangeRequestEntity.save();
        return shopEntity;
    }

    @Override
    public ShopCommentEntity createShopComment(String userId, String shopId, String title, String content) throws ShopException {
        if (StringUtil.isEmpty(content)) {
            throw new ShopException("评论内容不可为空");
        }
        ShopEntity shopEntity = findById(shopId);
        if (shopEntity == null) {
            throw new ShopException("找不到商店" + shopId);
        }
        ShopCommentEntity commentEntity = new ShopCommentEntity();
        commentEntity.setContent(content);
        commentEntity.setUserId(userId);
        commentEntity.setShopId(shopId);
        commentEntity.setTitle(title != null ? title : "");
        commentEntity.save();
        shopEntity.setShopCommentCount(shopEntity.getShopCommentCount() + 1);
        shopEntity.update();
        return commentEntity;
    }

    @Override
    public List<ShopCommentEntity> getShopLatestComments(String shopId, int limit) {
        return ShopCommentEntity.find.where().eq("shopId", shopId).orderBy("createTime", false).limit(limit).all();
    }

    @Override
    public List<ShopCommentEntity> getShopComments(String shopId, Paginator paginator) {
        paginator = paginator.eq("shopId", shopId).eq("deleted", IntBooleans.FALSE);
        paginator.getOrders().add(Pair.of("createTime", false));
        return ShopCommentEntity.find.findByPaginator(paginator);
    }

    @Override
    public void deleteShopComments(List<String> ids) {
        for(String id : ids) {
            ShopCommentEntity shopCommentEntity = ShopCommentEntity.find.byId(id);
            if(shopCommentEntity!=null && shopCommentEntity.getDeleted()!=IntBooleans.TRUE) {
                shopCommentEntity.setDeleted(IntBooleans.TRUE);
                shopCommentEntity.setModifyTime(TimeUtil.currentTimestamp());
                shopCommentEntity.update();
                ShopEntity shopEntity = findById(shopCommentEntity.getShopId());
                if(shopEntity!=null){
                    shopEntity.setShopCommentCount(shopEntity.getShopCommentCount()-1);
                    shopEntity.update();
                }
            }
        }
    }

    @Override
    public ShopFeedbackEntity createShopFeedback(String userId, String shopId, CreateShopFeedbackForm createShopFeedbackForm) throws ShopException {
        if(StringUtil.isEmpty(userId) || StringUtil.isEmpty(shopId)
                || StringUtil.isEmpty(createShopFeedbackForm.getTitle()) || StringUtil.isEmpty(createShopFeedbackForm.getContent())) {
            throw new ShopException("反馈信息不可为空");
        }
        ShopFeedbackEntity shopFeedbackEntity = new ShopFeedbackEntity();
        shopFeedbackEntity.setContent(createShopFeedbackForm.getContent());
        shopFeedbackEntity.setShopId(shopId);
        shopFeedbackEntity.setUserId(userId);
        shopFeedbackEntity.setName(createShopFeedbackForm.getName());
        shopFeedbackEntity.setPhone(createShopFeedbackForm.getPhone());
        shopFeedbackEntity.setTitle(createShopFeedbackForm.getContent());
        shopFeedbackEntity.save();
        return shopFeedbackEntity;
    }

    @Override
    public List<ShopFeedbackEntity> getShopFeedbacks(String shopId, Paginator paginator) {
        paginator = paginator.eq("shopId", shopId);
        paginator.getOrders().add(Pair.of("modifyTime", false));
        return ShopFeedbackEntity.find.findByPaginator(paginator);
    }

    @Override
    public ShopEntity findById(String id) {
        return ShopEntity.find.byId(id);
    }

    @Override
    public void collectShop(String shopId, String userId) {
        if(StringUtil.isEmpty(shopId) || StringUtil.isEmpty(userId)) {
            return;
        }
        ShopCollectEntity productCollectEntity = ShopCollectEntity.find.findByShopAndUser(shopId, userId);
        if(productCollectEntity == null) {
            productCollectEntity = new ShopCollectEntity();
            productCollectEntity.setShopId(shopId);
            productCollectEntity.setUserId(userId);
            productCollectEntity.save();
            ProductEntity productEntity = ProductEntity.find.byId(shopId);
            if (productEntity != null) {
                productEntity.setCollectCount(productEntity.getCollectCount() + 1);
                productEntity.update();
            }
        }
    }

    @Override
    public void unCollectShop(String shopId, String userId) {
        if(StringUtil.isEmpty(shopId) || StringUtil.isEmpty(userId)) {
            return;
        }
        ShopCollectEntity productCollectEntity = ShopCollectEntity.find.findByShopAndUser(shopId, userId);
        if(productCollectEntity != null) {
            productCollectEntity.delete();
            ProductEntity productEntity = ProductEntity.find.byId(shopId);
            if (productEntity != null) {
                productEntity.setCollectCount(productEntity.getCollectCount() - 1);
                if (productEntity.getCollectCount() < 0) {
                    productEntity.setCollectCount(0);
                }
                productEntity.update();
            }
        }
    }

    @Override
    public boolean isCollectedShop(String shopId, String userId) {
        if(StringUtil.isEmpty(shopId) || StringUtil.isEmpty(userId)) {
            return false;
        }
        ShopCollectEntity productCollectEntity = ShopCollectEntity.find.findByShopAndUser(shopId, userId);
        return productCollectEntity != null;
    }

    @Override
    public List<ShopEntity> getUserCollectedShops(String userId, Paginator paginator) {
        return ShopCollectEntity.find.getCollectedShopsByUser(userId, paginator);
    }

    @Override
    public List<ShopEntity> getShopsOwnedByUser(String userId) {
        return ShopEntity.find.where().eq("ownerId", userId).all();
    }

    @Override
    public void setShopsRelated(List<ShopEntity> shopEntities) {
        for (ShopEntity shopEntity : shopEntities) {
            shopEntity.setRelated();
        }
    }

    @Override
    public List<ShopEntity> getHotestShops(int limit) {
        return ShopEntity.find.where().orderBy("commentCount", false).limit(limit).all();
    }
}
